class LinkLogic {

    public static lines: number[][];

    public static isHaveLine(): boolean {
        LinkLogic.lines = [];
        let currentType: string = "";
        let typeNum: number = 0;

        // 行检测
        for (let i = 0; i < GameData.MaxRow; i++) {
            for (let j = 0; j < GameData.MaxColumn; j++) {
                let elementID: number = GameData.mapData[i][j];
                if (elementID != -1) {
                    let element: GameElement = GameData.elements[elementID];
                    if (currentType != element.type) {
                        if (typeNum >= 3) {
                            let arr: number[] = [];
                            for (let m = 0; m < typeNum; m++) {
                                arr.push(GameData.mapData[i][j - m - 1]);
                            }
                            LinkLogic.lines.push(arr);
                        }
                        currentType = element.type;
                        typeNum = 1;
                    } else {
                        typeNum++;
                    }
                } else {
                    if (typeNum >= 3) {
                        let arr: number[] = [];
                        for (let m = 0; m < typeNum; m++) {
                            arr.push(GameData.mapData[i][j - m - 1]);
                        }
                        LinkLogic.lines.push(arr);
                    }
                    currentType = "";
                    typeNum = 0;
                }
            }
            // 换行时检测一下
            if (typeNum >= 3) {
                let arr: number[] = [];
                for (let m = 0; m < typeNum; m++) {
                    arr.push(GameData.mapData[i][GameData.MaxColumn - m - 1]);
                }
                LinkLogic.lines.push(arr);
            }
            currentType = "";
            typeNum = 0;
        }

        // 列检测
        for (let j = 0; j < GameData.MaxColumn; j++) {
            for (let i = 0; i < GameData.MaxRow; i++) {
                let elementID: number = GameData.mapData[i][j];
                if (elementID != -1) {
                    let element: GameElement = GameData.elements[elementID];
                    if (currentType != element.type) {
                        if (typeNum >= 3) {
                            let arr: number[] = [];
                            for (let m = 0; m < typeNum; m++) {
                                arr.push(GameData.mapData[i - m - 1][j]);
                            }
                            LinkLogic.lines.push(arr);
                        }
                        currentType = element.type;
                        typeNum = 1;
                    } else {
                        typeNum++;
                    }
                } else {
                    if (typeNum >= 3) {
                        let arr: number[] = [];
                        for (let m = 0; m < typeNum; m++) {
                            arr.push(GameData.mapData[i - m - 1][j]);
                        }
                        LinkLogic.lines.push(arr);
                    }
                    currentType = "";
                    typeNum = 0;
                }
            }
            // 换行时检测一下
            if (typeNum >= 3) {
                let arr: number[] = [];
                for (let m = 0; m < typeNum; m++) {
                    arr.push(GameData.mapData[GameData.MaxRow - m - 1][j]);
                }
                LinkLogic.lines.push(arr);
            }
            currentType = "";
            typeNum = 0;
        }

        return LinkLogic.lines.length > 0;
    }

    public static isNextHaveLine(): boolean {

        // 情况1：同类型元素相邻的情况
        // #  #
        //  ##
        // #  #
        // 情况2：同类型元素间隔的情况
        //  #
        // # #
        //  #

        // 行检测
        for (let i = 0; i < GameData.MaxRow; i++) {
            for (let j = 0; j < GameData.MaxColumn; j++) {
                let elementID: number = GameData.mapData[i][j];
                if (elementID != -1) {
                    let element: GameElement = GameData.elements[elementID];
                    // 情况1
                    if (j < GameData.MaxColumn - 1) {
                        let nextElementID: number = GameData.mapData[i][j + 1];
                        if (nextElementID != -1 && element.type == GameData.elements[nextElementID].type) {
                            // 左
                            if (j > 0 && GameData.mapData[i][j - 1] != -1) {
                                if (i > 0 && GameData.mapData[i - 1][j - 1] != -1 && GameData.elements[GameData.mapData[i - 1][j - 1]].type == element.type) {
                                    return true; // 左上
                                }
                                if (i < GameData.MaxRow - 1 && GameData.mapData[i + 1][j - 1] != -1 && GameData.elements[GameData.mapData[i + 1][j - 1]].type == element.type) {
                                    return true; // 左下
                                }
                                if (j > 1 && GameData.mapData[i][j - 2] != -1 && GameData.elements[GameData.mapData[i][j - 2]].type == element.type) {
                                    return true; // 左左
                                }
                            }
                            // 右
                            if (j < GameData.MaxColumn - 2 && GameData.mapData[i][j + 2] != -1) {
                                if (i > 0 && GameData.mapData[i - 1][j + 2] != -1 && GameData.elements[GameData.mapData[i - 1][j + 2]].type == element.type) {
                                    return true; // 右上
                                }
                                if (i < GameData.MaxRow - 1 && GameData.mapData[i + 1][j + 2] != -1 && GameData.elements[GameData.mapData[i + 1][j + 2]].type == element.type) {
                                    return true; // 右下
                                }
                                if (j < GameData.MaxColumn - 3 && GameData.mapData[i][j + 3] != -1 && GameData.elements[GameData.mapData[i][j + 3]].type == element.type) {
                                    return true; // 右右
                                }
                            }
                        }
                    }
                    // 情况2
                    if (j < GameData.MaxColumn - 2) {
                        let nextElementID: number = GameData.mapData[i][j + 2];
                        if (nextElementID != -1 && element.type == GameData.elements[nextElementID].type) {
                            if (GameData.mapData[i][j + 1] != -1) {
                                // 上
                                if (i > 0 && GameData.mapData[i - 1][j + 1] != -1 && GameData.elements[GameData.mapData[i - 1][j + 1]].type == element.type) {
                                    return true;
                                }
                                // 下
                                if (i < GameData.MaxRow - 1 && GameData.mapData[i + 1][j + 1] != -1 && GameData.elements[GameData.mapData[i + 1][j + 1]].type == element.type) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        // 列检测
        for (let j = 0; j < GameData.MaxColumn; j++) {
            for (let i = 0; i < GameData.MaxRow; i++) {
                let elementID: number = GameData.mapData[i][j];
                if (elementID != -1) {
                    let element: GameElement = GameData.elements[elementID];
                    // 情况1
                    if (i < GameData.MaxRow - 1) {
                        let nextElementID: number = GameData.mapData[i + 1][j];
                        if (nextElementID != -1 && element.type == GameData.elements[nextElementID].type) {
                            // 上
                            if (i > 0 && GameData.mapData[i - 1][j] != -1) {
                                if (j > 0 && GameData.mapData[i - 1][j - 1] != -1 && GameData.elements[GameData.mapData[i - 1][j - 1]].type == element.type) {
                                    return true; // 左上
                                }
                                if (j < GameData.MaxColumn - 1 && GameData.mapData[i - 1][j + 1] != -1 && GameData.elements[GameData.mapData[i - 1][j + 1]].type == element.type) {
                                    return true; // 右上
                                }
                                if (i > 1 && GameData.mapData[i - 2][j] != -1 && GameData.elements[GameData.mapData[i - 2][j]].type == element.type) {
                                    return true; // 上上
                                }
                            }
                            // 下
                            if (i < GameData.MaxRow - 2 && GameData.mapData[i + 2][j] != -1) {
                                if (j > 0 && GameData.mapData[i + 2][j - 1] != -1 && GameData.elements[GameData.mapData[i + 2][j - 1]].type == element.type) {
                                    return true; // 左下
                                }
                                if (j < GameData.MaxColumn - 1 && GameData.mapData[i + 2][j + 1] != -1 && GameData.elements[GameData.mapData[i + 2][j + 1]].type == element.type) {
                                    return true; // 右下
                                }
                                if (i < GameData.MaxRow - 3 && GameData.mapData[i + 3][j] != -1 && GameData.elements[GameData.mapData[i + 3][j]].type == element.type) {
                                    return true; // 下下
                                }
                            }
                        }
                    }
                    // 情况2
                    if (i < GameData.MaxRow - 2) {
                        let nextElementID: number = GameData.mapData[i + 2][j];
                        if (nextElementID != -1 && element.type == GameData.elements[nextElementID].type) {
                            if (GameData.mapData[i + 1][j] != -1) {
                                // 左
                                if (j > 0 && GameData.mapData[i + 1][j - 1] != -1 && GameData.elements[GameData.mapData[i + 1][j - 1]].type == element.type) {
                                    return true;
                                }
                                // 右
                                if (j < GameData.MaxColumn - 1 && GameData.mapData[i + 1][j + 1] != -1 && GameData.elements[GameData.mapData[i + 1][j + 1]].type == element.type) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public static canMove(p1: number, p2: number): boolean {

        let element1row: number = Math.floor(GameData.elements[p1].location / GameData.MaxRow);
        let element1col: number = GameData.elements[p1].location % GameData.MaxColumn;
        let element2row: number = Math.floor(GameData.elements[p2].location / GameData.MaxRow);
        let element2col: number = GameData.elements[p2].location % GameData.MaxColumn;

        if ((element1row == element2row && Math.abs(element1col - element2col) == 1) ||
            (element1col == element2col && Math.abs(element1row - element2row) == 1)) {
            return true;
        }
        return false;
    }

    public static changeOrder() {
        let arr: number[];
        for (let i = 0; i < GameData.MaxRow; i++) {
            for (let j = 0; j < GameData.MaxColumn; j++) {
                if (GameData.mapData[i][j] != -1) {
                    arr.push(GameData.mapData[i][j]);
                }
            }
        }

        let index: number = 0;
        for (let i = 0; i < GameData.MaxRow; i++) {
            for (let j = 0; j < GameData.MaxColumn; j++) {
                index = Math.floor(Math.random() * arr.length);
                GameData.mapData[i][j] = arr[index];
                GameData.elements[arr[index]].location = i * GameData.MaxColumn + j;
                arr.slice(index, i);
            }
        }
    }

    public static isHaveLineByIndex(p1: number, p2: number): boolean {

        let element1row: number = Math.floor(GameData.elements[p1].location / GameData.MaxRow);
        let element1col: number = GameData.elements[p1].location % GameData.MaxColumn;
        let element2row: number = Math.floor(GameData.elements[p2].location / GameData.MaxRow);
        let element2col: number = GameData.elements[p2].location % GameData.MaxColumn;

        let p1n: number = p1;
        let p2n: number = p2;
        let p1id: number = GameData.mapData[element1row][element1col];
        let p2id: number = GameData.mapData[element2row][element2col];

        GameData.mapData[element1row][element1col] = p2id;
        GameData.mapData[element2row][element2col] = p1id;

        if (LinkLogic.isHaveLine()) {
            GameData.elements[p1id].location = p2;
            GameData.elements[p2id].location = p1;
            return true;
        } else {
            GameData.mapData[element1row][element1col] = p1id;
            GameData.mapData[element2row][element2col] = p2id;
        }
        return false;
    }






}